package lmh.example.exam2_1;


import android.opengl.GLSurfaceView;

import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.FloatBuffer;
import java.nio.IntBuffer;

import javax.microedition.khronos.egl.EGLConfig;
import javax.microedition.khronos.opengles.GL10;

public class MyRenderer implements GLSurfaceView.Renderer {
    //点的坐标数组
    private float[] mArray = {0f, 0f, 0f};

    // 分别指定三个顶点的位置坐标，每个顶点需要指定三个坐标，分别是X、Y、Z坐标轴方向的数据;
    // OpenGL 只会渲染坐标值范围在 [-1, 1] 的内容
    private float vertexArray[] = {
            0.0f, 0.9f, 0.0f,   // 上顶点位置坐标
            -0.4f, 0.1f, 0.0f, // 左下顶点位置坐标
            0.4f, 0.1f, 0.0f   // 右下顶点位置坐标
            //以上位置坐标z都为0，将创建一个平面图形
    };
    // 缓冲区
    private FloatBuffer mBuffer;
    private FloatBuffer vertextmBuffer;

    public MyRenderer() {
        //获取浮点型缓冲数据
        mBuffer = floatBufferUtil(mArray);
        vertextmBuffer = floatBufferUtil(vertexArray);
    }

    // GLSurfaceView创建时调用
    @Override
    public void onSurfaceCreated(GL10 gl, EGLConfig config) {
        // 设置清屏颜色为黑色（相当于给GLSurfaceView控件设置背景色）。
        // 此处alpha设置为0或1没有区别，都是黑色。
        gl.glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
    }

    // GLSurfaceView尺寸改变时调用
    @Override
    public void onSurfaceChanged(GL10 gl, int width, int height) {
        // 第一个参数和第二个参数用于设置视口在GLSurfaceView中的位置，此处的（0，0）代表GLSurfaceView的左下角
        // 第三个参数和第四个参数用于设置视口的宽和高。
        gl.glViewport(0, 0, width, height);
//        gl.glViewport(0, 0, width / 2, height / 2);
//        gl.glViewport(width / 2, height / 2, width / 2, height / 2);
    }

    // 在GLSurfaceView上绘制时调用
    @Override
    public void onDrawFrame(GL10 gl) {
        // 清除屏幕缓存
        gl.glClear(GL10.GL_COLOR_BUFFER_BIT);
        // 启用顶点缓冲区。GL10.GL_VERTEX_ARRAY：顶点数组
        gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);

        // --------------------绘制第一个图形（一个点）---------------------
        // 设置顶点位置数据
        gl.glVertexPointer(3, GL10.GL_FLOAT, 0, mBuffer);
        //设置点的颜色为绿色
        gl.glColor4f(0.0f, 1.0f, 0.0f, 1.0f);
        //设置点的大小
        gl.glPointSize(80f);
        // 绘制点
        gl.glDrawArrays(GL10.GL_POINTS, 0, 1);

        // --------------------绘制第二个图形（三个顶点组成两条线段或三角形）---------------------
        // 设置顶点位置数据
        gl.glVertexPointer(3, GL10.GL_FLOAT, 0, vertextmBuffer);
        //设置点的颜色为红色
        gl.glColor4f(1.0f, 0.0f, 0.0f, 1.0f);
        //设置线宽
        gl.glLineWidth(40f);
        // 绘制线带，此处将绘制两条线段
        gl.glDrawArrays(GL10.GL_LINE_STRIP, 0, 3);
        // 绘制一个三角形
//        gl.glDrawArrays(GL10.GL_TRIANGLES, 0, 3);

        // 禁止顶点设置
        gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);
    }

    // 定义一个工具方法，将float[]数组转换为OpenGL ES所需的FloatBuffer。
    private FloatBuffer floatBufferUtil(float[] arr) {
        FloatBuffer mBuffer;
        // 初始化形状中顶点坐标数据的字节缓冲区，
        // 通过 ByteBuffer的allocateDirect()方法获取到ByteBuffer实例，
        // 长度则为arr数组的长度*4，因为一个float占4字节
        ByteBuffer qbb = ByteBuffer.allocateDirect(arr.length * 4);
        // 数组排列用nativeOrder。
        // 注意：这里有个排序的问题，是使用大端（BIG_ENDIAN）还是用小端（LITTLE_ENDIAN），
        // 在Android里面，opengl画图must use native order direct buffer,否则报错，
        // 这里我们直接使用allocateDirect和nativeOrder，就能满足Android的要求。
        qbb.order(ByteOrder.nativeOrder());
        // 因为 ByteBuffer 是将数据移进移出通道的唯一方式，
        // 这里使用 “as” 方法从 ByteBuffer字节缓冲区中获得一个基本类型缓冲区，即浮点缓冲区FloatBuffer
        mBuffer = qbb.asFloatBuffer();
        // 把顶点坐标信息数组arr存储到 FloatBuffer。
        mBuffer.put(arr);
        // 设置从缓冲区的第一个位置开始读取顶点坐标信息。
        mBuffer.position(0);
        return mBuffer;
    }
}